package com.zlyx.easy.socket.core.supports;

import java.net.InetAddress;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.zlyx.easy.core.annotations.Desc;
import com.zlyx.easy.core.thread.BlockThread;
import com.zlyx.easy.core.tool.Hex;
import com.zlyx.easy.core.utils.ByteUtils;
import com.zlyx.easy.core.utils.ClassUtils;
import com.zlyx.easy.core.utils.JsonUtils;
import com.zlyx.easy.core.utils.ObjectUtils;
import com.zlyx.easy.socket.interfaces.IMsgHandler;

/**
 * 
 * @author 赵光
 * @Description: 消息处理工厂抽象类
 * @date 2018年11月14日
 */
@Desc("消息处理工厂抽象类")
public abstract class AbstractMsgHandlerFactory extends BlockThread {

	private ConcurrentMap<InetAddress, IMsgHandler<?>> handlers = new ConcurrentHashMap<InetAddress, IMsgHandler<?>>();

	protected Logger logger = LoggerFactory.getLogger(IMsgHandler.class);

	protected IMsgHandler<?> handler;
	protected Class<?> tClass;
	protected int BLOCK = 1024;
	protected int PORT;

	public AbstractMsgHandlerFactory(int port, float size, IMsgHandler<?> handler) {
		this.handler = handler;
		this.tClass = this.handler.getTClass();
		this.BLOCK = (int) (BLOCK * size);
		this.PORT = port;
	}

	private IMsgHandler<?> getMsgHandler(InetAddress address) {
		if (address == null) {
			return this.handler;
		}
		IMsgHandler<?> handler = handlers.get(address);
		if (handler == null) {
			handler = ClassUtils.newInstance(this.handler.getClass());
			handlers.put(address, handler);
		}
		return handler;
	}

	protected byte[] doHandler(String msg) throws Exception {
		return doHandler(null, msg);
	}

	@SuppressWarnings("unchecked")
	protected byte[] doHandler(InetAddress address, String msg) throws Exception {
		IMsgHandler<?> handler = getMsgHandler(address);
		if (JSONObject.class == tClass) {
			JSONObject res = ((IMsgHandler<JSONObject>) handler).doHandle(JsonUtils.parse(msg));
			if (ObjectUtils.isNotEmpty(res)) {
				return res.toString().getBytes();
			}
		} else if (byte[].class == tClass) {
			byte[] res = ((IMsgHandler<byte[]>) handler).doHandle(msg.getBytes());
			if (ObjectUtils.isNotEmpty(res)) {
				return res;
			}
		} else if (Hex.class == tClass) {
			Hex res = ((IMsgHandler<Hex>) handler).doHandle(Hex.newHex(ByteUtils.bytesToHexString(msg.getBytes())));
			if (ObjectUtils.isNotEmpty(res)) {
				return ByteUtils.hexStringToByte(res.getHex());
			}
		} else if (String.class == tClass) {
			String res = ((IMsgHandler<String>) handler).doHandle(msg);
			if (ObjectUtils.isNotEmpty(res)) {
				return res.getBytes();
			}
		} else {
			Object res = ((IMsgHandler<Object>) handler).doHandle(msg);
			if (ObjectUtils.isNotEmpty(res)) {
				return String.valueOf(res).getBytes();
			}
		}
		return new byte[0];
	}

	/**
	 * 关闭服务
	 */
	public abstract void closeServer() throws Exception;
}
